package com.anysoft.util;

import com.google.re2j.Matcher;
import com.google.re2j.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.TimeZone;

/**
 * 时间段
 * @since 1.6.13.7 [20200720 duanyy] <br>
 */
public final class TimeBucket {
    /**
     * a logger of slf4j
     */
    private static final Logger LOG = LoggerFactory.getLogger(TimeBucket.class);
    private static final long oneDay = 86400000L;
    private int startTime = 2400;
    private int endTime = 2359;
    private int minuteOffset = 480;

    private static Pattern all = Pattern.compile("^(\\d*)\\-(\\d*)\\+([\\+\\-]?\\d*)$");
    private static Pattern noOffset = Pattern.compile("^(\\d*)\\-(\\d*)$");
    private static Pattern noEndTime = Pattern.compile("^(\\d*)$");

    public TimeBucket(String pattern){
        parse(pattern);
    }

    private void parse(String pattern) {
        Matcher matcher = all.matcher(pattern);
        if (matcher.find()){
            startTime = getInt(matcher.group(1),2400);
            endTime = getInt(matcher.group(2),2359);
            minuteOffset = getInt(matcher.group(3),-480);
        }else{
            matcher = noOffset.matcher(pattern);
            if (matcher.find()){
                startTime = getInt(matcher.group(1),2400);
                endTime = getInt(matcher.group(2),2359);
            }else{
                matcher = noEndTime.matcher(pattern);
                if (matcher.find()){
                    startTime = getInt(matcher.group(1),2400);
                }else{
                    LOG.error("Pattern is not match:" + pattern);
                }
            }
        }
    }

    public static boolean check(String pattern){
        Matcher matcher = all.matcher(pattern);
        if (matcher.find()){
            return true;
        }else{
            matcher = noOffset.matcher(pattern);
            if (matcher.find()){
                return true;
            }else{
                matcher = noEndTime.matcher(pattern);
                return matcher.find();
            }
        }
    }

    public void setPattern(String pattern){
        this.parse(pattern);
    }

    private int getInt(String v,int dft){
        try {
            return Integer.parseInt(v);
        }catch(NumberFormatException ex){
            return dft;
        }
    }

    private int getMinutes(int value){
        return (value / 100) * 60 + (value % 100) * 60;
    }

    public boolean match(long now){
        now = now <= 0 ? System.currentTimeMillis() : now;
        long offset = TimeZone.getDefault().getOffset(now);
        long minutes = (now - (((now + offset) / oneDay) *oneDay))/60000;
        return minutes + minuteOffset >= getMinutes(startTime) && minutes + minuteOffset < getMinutes(endTime);
    }
}
